home *** CD-ROM | disk | FTP | other *** search
/ Aminet 24 / Aminet 24 (1998)(GTI - Schatztruhe)[!][Apr 1998].iso / Aminet / game / shoot / ADoom_src_1_1.lha / ADoom_src / amiga_ipx.c < prev    next >
C/C++ Source or Header  |  1998-02-06  |  12KB  |  406 lines

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <stdarg.h>
  4. #include <string.h>
  5. #include <dos.h>
  6.  
  7. #include <exec/exec.h>
  8. #include <devices/sana2.h>
  9. #include <proto/exec.h>
  10.  
  11. #include "i_system.h"
  12. #include "amiga_ipx.h"
  13.  
  14. /**********************************************************************/
  15. // This file isn't used in ADoom.
  16. // It's rather buggy.
  17. // It implements an crude IPX layer using any ethernet sana2 device.
  18. // I wrote it out of frustration when I couldn't get amipx.library v1.0
  19. // to work.  Peter Mcgavin, 5 Feb 1998.
  20.  
  21. /**********************************************************************/
  22. struct request {
  23.   struct MinNode node;
  24.   struct IPXECB *ecb;
  25.   struct IOSana2Req *io;
  26.   BOOL io_in_progress;
  27. };
  28.  
  29. static struct MsgPort *sana2_mp = NULL;
  30. static struct IOSana2Req *sana2_io = NULL;
  31. static BOOL sana2_is_open = FALSE;
  32. static UWORD the_socket = 0;  /* we handle only one socket at a time */
  33. static int the_packettype = 0;
  34. static struct IPXAddress localaddress = {
  35.   {'\0', '\0', '\0', '\0'},
  36.   {'\0', '\0', '\0', '\0', '\0', '\0'},
  37.   0
  38. };
  39. static struct request *req_to_relinquish;
  40. static struct MinList req_list;  /* list of possibly outstanding requests */
  41.  
  42. /**********************************************************************/
  43. static int ecb_length (struct IPXECB *ecb)
  44. {
  45.   int i, len;
  46.  
  47.   len = 0;
  48.   for (i = 0; i < ecb->FragCount; i++)
  49.     len += ecb->Fragment[i].FragSize;
  50.   return len;
  51. }
  52.  
  53. /**********************************************************************/
  54. static BOOL __asm __interrupt __saveds CopyFromBuff (  // send
  55.   register __a0 UBYTE *to,
  56.   register __a1 struct IPXECB *ecb,
  57.   register __d0 LONG n)
  58. {
  59.   int i, len, rem;
  60.   struct IPXPacketHeader *ph;
  61.  
  62.   ph = (struct IPXPacketHeader *)ecb->Fragment[0].FragData;
  63.  
  64.   *to++ = 0xe0;  /* Ethernet 802.2 3-byte header */
  65.   *to++ = 0xe0;
  66.   *to++ = 0x03;
  67.   n -= 3;
  68.   len = ecb_length (ecb);
  69.   if (n < len)
  70.     len = n;
  71.  
  72.   *to++ = 0xff; /* checksum[0] */
  73.   *to++ = 0xff; /* checksum[1] */
  74.   *to++ = len >> 8;   /* length[0] */
  75.   *to++ = len & 255;  /* length[1] */
  76.   *to++ = ph->Tc;
  77.   *to++ = ph->Type;
  78.   memcpy (to, &ph->Dst, sizeof(struct IPXAddress));
  79.   to += sizeof(struct IPXAddress);
  80.   memcpy (to, &localaddress, sizeof(struct IPXAddress));
  81.   to += sizeof(struct IPXAddress);
  82.   n -= sizeof(struct IPXPacketHeader);
  83.  
  84.   if (n > 0) {
  85.  
  86.     rem = ecb->Fragment[0].FragSize - sizeof(struct IPXPacketHeader);
  87.     if (rem > 0) {
  88.       if (n < rem)
  89.         rem = n;
  90.       memcpy (to, &ecb->Fragment[0].FragData[sizeof(struct IPXPacketHeader)],
  91.               rem);
  92.       to += rem;
  93.       n -= rem;
  94.     }
  95.  
  96.     for (i = 1; i < ecb->FragCount && n > 0; i++) {
  97.       rem = ecb->Fragment[i].FragSize;
  98.       if (n < rem)
  99.         rem = n;
  100.       memcpy (to, ecb->Fragment[i].FragData, rem);
  101.       to += rem;
  102.       n -= rem;
  103.     }
  104.   }
  105.  
  106.   /* invoke ESR here */
  107.   ecb->InUse = 0;
  108.   return TRUE;
  109. }
  110.  
  111. /**********************************************************************/
  112. static BOOL __asm __interrupt __saveds CopyToBuff ( // get
  113.   register __a0 struct IPXECB *ecb,
  114.   register __a1 UBYTE *from,
  115.   register __d0 LONG n)
  116. {
  117.   int i, rem;
  118.  
  119.   from += 3;  /* skip Ethernet 802.2 3-byte header */
  120.   n -= 3;
  121.   for (i = 0; i < ecb->FragCount && n > 0; i++) {
  122.     rem = ecb->Fragment[i].FragSize;
  123.     if (n < rem)
  124.       rem = n;
  125.     memcpy (ecb->Fragment[i].FragData, from, rem);
  126.     from += rem;
  127.     n -= rem;
  128.   }
  129.   memcpy (ecb->ImmedAddr,
  130.          ((struct IPXPacketHeader *)ecb->Fragment[0].FragData)->Src.Node, 6);
  131.   /* invoke ESR here */
  132.   ecb->InUse = 0;
  133.   return TRUE;
  134. }
  135.  
  136. /**********************************************************************/
  137. /*
  138. static BOOL __asm __interrupt __saveds PacketFilter (
  139.   register __a0 struct Hook *hook,
  140.   register __a2 struct IOSana2Req *ios2,
  141.   register __a1 APTR data)
  142. {
  143.   return TRUE;
  144. }
  145. */
  146.  
  147. /**********************************************************************/
  148. void Init_IPX (char *sana2devicename, int unit, int packettype)
  149. {
  150. /*
  151.   int i;
  152.   static struct Hook packetfilterhook = {
  153.     {NULL},
  154.     (ULONG (*)())PacketFilter,
  155.     NULL,
  156.     NULL
  157.   };
  158. */
  159.   static struct TagItem ios2_tags[] = {
  160.     {S2_CopyToBuff,   (ULONG)CopyToBuff},
  161.     {S2_CopyFromBuff, (ULONG)CopyFromBuff},
  162.   /*{S2_PacketFilter, (ULONG)&packetfilterhook},*/
  163.     {TAG_DONE,        0}
  164.   };
  165.  
  166.   NewList ((struct List *)&req_list);
  167.  
  168.   the_packettype = packettype;
  169.  
  170.   if ((sana2_mp = CreatePort (NULL, 0)) == NULL ||
  171.       (sana2_io = (struct IOSana2Req *)CreateExtIO (sana2_mp,
  172.                                            sizeof(struct IOSana2Req))) == NULL)
  173.     I_Error ("Can't create port");
  174.  
  175.   sana2_io->ios2_BufferManagement = ios2_tags;
  176.  
  177.   if (OpenDevice (sana2devicename, unit, (struct IORequest *)sana2_io, 0) != 0)
  178.     I_Error ("Can't open %s, unit %d", sana2devicename, unit);
  179.   sana2_is_open = TRUE;
  180.  
  181.   sana2_io->ios2_Req.io_Command = S2_CONFIGINTERFACE;
  182.   sana2_io->ios2_Req.io_Flags = 0; /* SANA2IOF_QUICK */
  183.   memset (sana2_io->ios2_SrcAddr, 0, SANA2_MAX_ADDR_BYTES);
  184.   DoIO ((struct IORequest *)sana2_io);
  185.  
  186.   sana2_io->ios2_Req.io_Command = S2_GETSTATIONADDRESS;
  187.   DoIO ((struct IORequest *)sana2_io);
  188.   if (sana2_io->ios2_Req.io_Error != 0)
  189.     I_Error ("Error %d getting station address", sana2_io->ios2_Req.io_Error);
  190.   memcpy (localaddress.Node, sana2_io->ios2_SrcAddr,
  191.           sizeof(localaddress.Node));
  192. /*
  193.   printf ("Source address =");
  194.   for (i = 0; i < SANA2_MAX_ADDR_BYTES; i++)
  195.       printf (" %02x", sana2_io->ios2_SrcAddr[i]);
  196.   printf ("\n");
  197.   printf ("Dest address   =");
  198.   for (i = 0; i < SANA2_MAX_ADDR_BYTES; i++)
  199.       printf (" %02x", sana2_io->ios2_DstAddr[i]);
  200.   printf ("\n");
  201. */
  202. }
  203.  
  204. /**********************************************************************/
  205. void Shutdown_IPX (void)
  206. {
  207.   struct request *req;
  208.   struct MinNode *succ;
  209.  
  210.   if (sana2_is_open) {
  211.     /* abort and free outstanding requests */
  212.     req = (struct request *)req_list.mlh_Head;
  213.     succ = req->node.mln_Succ;
  214.     while (succ != NULL) {
  215.       if (req->io_in_progress) {
  216.         AbortIO ((struct IORequest *)req->io);
  217.         WaitIO ((struct IORequest *)req->io);
  218.         req->io_in_progress = FALSE;
  219.         req->ecb->InUse = 0;
  220.       }
  221.       DeleteExtIO ((struct IORequest *)req->io);
  222.       Remove ((struct Node *)&req->node);
  223.       FreeMem (req, sizeof(struct request));
  224.       req = (struct request *)succ;
  225.       succ = req->node.mln_Succ;
  226.     }
  227.     CloseDevice ((struct IORequest *)sana2_io);
  228.     sana2_is_open = FALSE;
  229.   }
  230.   if (sana2_io != NULL) {
  231.     DeleteExtIO ((struct IORequest *)sana2_io);
  232.     sana2_io = NULL;
  233.   }
  234.   if (sana2_mp != NULL) {
  235.     DeletePort (sana2_mp);
  236.     sana2_mp = NULL;
  237.   }
  238. }
  239.  
  240. /**********************************************************************/
  241. UWORD IPXOpenSocket (UWORD socketid)
  242. {
  243.   if (the_socket != 0)
  244.     return 0;
  245.   the_socket = socketid;
  246.   localaddress.Socket = socketid;
  247.   return the_socket;
  248. }
  249.  
  250. /**********************************************************************/
  251. void IPXCloseSocket (UWORD socketid)
  252. {
  253.   the_socket = 0;
  254. }
  255.  
  256. /**********************************************************************/
  257. int IPXGetLocalTarget (struct IPXAddress *request, UBYTE reply[6])
  258. {
  259.   memcpy (reply, request->Node, 6);
  260.   return 1;
  261. }
  262.  
  263. /**********************************************************************/
  264. void IPXSendPacket (struct IPXECB *ecb)
  265. {
  266.   struct request *req;
  267.   struct IPXPacketHeader *ph;
  268.  
  269.   req = *(struct request **)ecb->IPXWork;
  270.   if (req == NULL) {
  271.     if ((req = (struct request *)AllocMem (sizeof(struct request),
  272.                                            MEMF_CLEAR)) == NULL ||
  273.         (req->io = (struct IOSana2Req *)CreateExtIO (sana2_mp,
  274.                                            sizeof(struct IOSana2Req))) == NULL)
  275.       I_Error ("Can't create port or IO");
  276.     *((struct request **)ecb->IPXWork) = req;
  277.     req->io_in_progress = FALSE;
  278.     *req->io = *sana2_io;
  279.     req->io->ios2_Req.io_Flags = 0; /* SANA2IOF_RAW | SANA2IOF_QUICK */
  280.     req->io->ios2_PacketType = the_packettype; /* 802.3 */  /* 0x8137 Novell */
  281.                                             /* 2049 Envoy IP, 2055 Envoy ARP */
  282.     req->ecb = ecb;
  283.     AddTail ((struct List *)&req_list, (struct Node *)&req->node);
  284.   } else if (req->io_in_progress) {
  285.     WaitIO ((struct IORequest *)sana2_io);
  286.